package edu.purdue.cs.aggr.messageprocessor;

import java.util.HashMap;
import java.util.Map;

import edu.purdue.cs.aggr.Accumulator;
import edu.purdue.cs.aggr.AccumulatorFactory;
import edu.purdue.cs.aggr.AggrException;
import edu.purdue.cs.aggr.InputReader;
import edu.purdue.cs.aggr.Vertex;
import edu.purdue.cs.aggr.VertexManager;
import edu.purdue.cs.aggr.message.EventMessageBuilder;
import edu.purdue.cs.aggr.message.EventNotificationMessage.Event;
import edu.purdue.cs.aggr.message.Message;

public class VertexUpdateMessageProcessor extends MessageProcessor 
{
  
  private VertexManager manager;
  
  public VertexUpdateMessageProcessor (VertexManager m) {
    this.manager = m;
  }

  @Override
  public void processMessage(Message message) throws AggrException
  {
    Vertex vertex = manager.getVertex(message.getDestination());
    System.out.println(vertex.getId() + ": Processing update message... (dest " + message.getDestination() + ")");
    
    // tell my parent that I'm going to update
    manager.sendMessage(EventMessageBuilder.createEventMessage(vertex, Event.BEGINNING_UPDATE, vertex.getDestinationVertex(), null));
    
    // generate some new random data and make the vertex redo its computation
    Map<String, Object> params = new HashMap<String, Object>();
    params.put(AccumulatorFactory.PARAMETER_YVALUE, vertex.getAccumulatorSubtype()); 
    params.put(AccumulatorFactory.PARAMETER_KVAUE, vertex.getAccumulatorSubtype()); 
    Accumulator newData = AccumulatorFactory.getEmptyAccumulator(vertex.getAccumulatorType(), params, vertex.getId() );
    long procTime = InputReader.populateAccumulatorFromRandomInput(newData);
    vertex.setStoredAccumulator(newData);
    manager.sendMessage(EventMessageBuilder.createEventMessage(vertex, Event.UPDATE_DONE_PROCESSING, new Long(procTime)));
    System.out.println(vertex.getId() + ": Sending UPDATE_DONE_PROCESSING to controller time: " + procTime);
  }
}
